﻿
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HaumDisplay
{
    public class HaumCircle : HaumShape
    {
        /// <summary>
        /// 圆心坐标
        /// </summary>
        public PointF center;

        /// <summary>
        /// 半径
        /// </summary>
        public float radius;

        internal Pen pen;

        /// <summary>
        /// 反色
        /// </summary>
        internal Color invertColor;

        /// <summary>
        /// 是否选中
        /// </summary>
        internal bool isSelect;

        /// <summary>
        /// 开始绘制
        /// </summary>
        internal bool startGraphic;

        public HaumCircle(Color color, int borderSize = 1) {
            this.center = PointF.Empty;
            this.radius = 0;
            this.pen = new Pen(color, borderSize);
            //this.invertColor = Color.FromArgb(255 - color.R, 255 - color.G, 255 - color.B);
            this.invertColor = Color.FromArgb(color.R / 2, color.G / 2, color.B / 2);
            this.isSelect = false;
            this.startGraphic = false;
        }

        /// <summary>
        /// 获取圆直径
        /// </summary>
        /// <returns></returns>
        public float GetDiameter() {
            return radius * 2;
        }

        /// <summary>
        /// 获取圆面积
        /// </summary>
        /// <returns></returns>
        public double GetCircleArea() {
            double s = Math.PI * Math.Pow(radius, 2);
            return s;
        }

        /// <summary>
        /// 获取圆周长
        /// </summary>
        /// <returns></returns>
        public double GetPerimeter() {
            double p = 2 * Math.PI * radius;
            return p;
        }

        /// <summary>
        /// 获取缩放点
        /// </summary>
        /// <returns></returns>
        public PointF GetScalePointF()
        {
            PointF scalePoint = new PointF(center.X + radius, center.Y);
            return scalePoint;
        }

        /// <summary>
        /// 获取圆的最小外接矩形
        /// </summary>
        /// <returns></returns>
        public Rectangle GetBindRect()
        {
            //计算外接矩形左上角坐标
            Point tl = new Point((int)(center.X - radius), (int)(center.Y - radius));
            Size size = new Size((int)(radius * 2), (int)(radius * 2));
            return new Rectangle(tl, size);
        }

        public RectangleF GetBindRectF()
        {
            //计算外接矩形左上角坐标
            PointF tl = new PointF(center.X - radius, center.Y - radius);
            SizeF size = new SizeF(radius * 2, radius * 2);
            return new RectangleF(tl, size);
        }

        /// <summary>
        /// 获取圆的轮廓点
        /// </summary>
        /// <param name="distance">相邻点之间的距离</param>
        /// <returns></returns>
        public List<Point> GetContours(int distance) {
            List<Point> contourPoints = new List<Point>();

            // 避免无效参数
            if (radius <= 0 || distance <= 0)
                return contourPoints;

            // 计算圆的周长
            float circumference = 2 * (float)Math.PI * radius;

            // 计算需要的点数（向上取整）
            int pointCount = (int)Math.Ceiling(circumference / distance);

            // 确保至少有4个点来形成一个圆
            pointCount = Math.Max(pointCount, 4);

            // 计算每个点之间的角度增量（弧度）
            double angleIncrement = 2 * Math.PI / pointCount;

            // 计算每个点的坐标并添加到列表
            for (int i = 0; i < pointCount; i++)
            {
                double angle = i * angleIncrement;

                // 计算点的X坐标（图像坐标系中Y轴向下为正）
                float x = center.X + radius * (float)Math.Cos(angle);
                // 注意：图像坐标系中Y轴向下为正，与数学坐标系不同
                float y = center.Y + radius * (float)Math.Sin(angle);

                contourPoints.Add(new Point((int)x, (int)y));
            }

            return contourPoints;
        }

        public List<PointF> GetContoursF(int distance)
        {
            List<PointF> contourPoints = new List<PointF>();

            // 避免无效参数
            if (radius <= 0 || distance <= 0)
                return contourPoints;

            // 计算圆的周长
            float circumference = 2 * (float)Math.PI * radius;

            // 计算需要的点数（向上取整）
            int pointCount = (int)Math.Ceiling(circumference / distance);

            // 确保至少有4个点来形成一个圆
            pointCount = Math.Max(pointCount, 4);

            // 计算每个点之间的角度增量（弧度）
            double angleIncrement = 2 * Math.PI / pointCount;

            // 计算每个点的坐标并添加到列表
            for (int i = 0; i < pointCount; i++)
            {
                double angle = i * angleIncrement;

                // 计算点的X坐标（图像坐标系中Y轴向下为正）
                float x = center.X + radius * (float)Math.Cos(angle);
                // 注意：图像坐标系中Y轴向下为正，与数学坐标系不同
                float y = center.Y + radius * (float)Math.Sin(angle);

                contourPoints.Add(new PointF(x, y));
            }

            return contourPoints;
        }

        public override string ToString()
        {
            return $"圆中心坐标:[{center.X},{center.Y}]-半径R:[{radius.ToString("f3")}]-直径D:[{this.GetDiameter().ToString("f3")}]-周长:[{this.GetPerimeter().ToString("f3")}]-面积:[{this.GetCircleArea().ToString("f3")}]";
        }

        public override void Graphic(Graphics g, GraphicHelper myGraphic)
        {

            g.SmoothingMode = SmoothingMode.HighQuality;

            //绘制圆心小十字
            //获取圆心像素坐标 转换成控件坐标
            PointF center = Tools.ImageTransScreenPointF(this.center, myGraphic.scale, myGraphic.offset);
            //根据中心坐标拟合两条垂直线
            // 绘制垂直的线（中心点上下各 3 像素）
            g.DrawLine(this.pen, center.X, center.Y - 5, center.X, center.Y + 5);
            // 绘制水平的线（中心点左右各 3 像素）
            g.DrawLine(this.pen, center.X - 5, center.Y, center.X + 5, center.Y);
            //圆的中心坐标转控件坐标
            PointF tl = Tools.ImageTransScreenPointF(new PointF(this.center.X - this.radius, this.center.Y - this.radius), myGraphic.scale, myGraphic.offset);
            PointF br = Tools.ImageTransScreenPointF(new PointF(this.center.X + this.radius, this.center.Y + this.radius), myGraphic.scale, myGraphic.offset);
            SizeF size = new SizeF(br.X - tl.X, br.Y - tl.Y);
            g.DrawEllipse(this.pen, new RectangleF(tl, size));

            using (Brush brush = new SolidBrush(this.isSelect ? this.invertColor : this.pen.Color))
            {
                //int r = (int)this.pen.Width * 3;
                //PointF rightPoint = Tools.ImageTransScreenPointF(this.GetScalePointF(), myGraphic.scale, myGraphic.offset);
                //绘制拖动缩放点
                //g.FillEllipse(brush, rightPoint.X - r / 2, rightPoint.Y - r / 2, r, r);
            }
        }
    }
}
